
package capa_logica;

import capa_persistencia.AccesoBD;
import capa_persistencia.CreadorBD;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Escenario 
{
    private int id;
    private String nombre;
    private int largo;
    private int ancho;
    private Celda [][] matriz;
    
    public static int TAM_CELDA = 5;
    public static int LARGO = 1245;
    public static int ANCHO = 700;
    
    public Escenario(int id, String nombre) 
    {
        this.id = id;
        this.nombre = nombre;
        this.largo = LARGO;
        this.ancho = ANCHO;
        matriz = new Celda[largo / TAM_CELDA][ancho / TAM_CELDA];
        inicializarMatriz();
        
        cargarObstaculos();
    }
    
    private void cargarObstaculos()
    {
        try {
            Properties p = new Properties();
            String nomArch = "datos.properties";
            InputStream in;
            in = CreadorBD.class.getResourceAsStream(nomArch);
            p.load(in);
            String url = p.getProperty("url");
            String user = p.getProperty("user");
            String pass = p.getProperty("pass");
            in.close();
            
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection(url + "partidasguardadas", user, pass);
            AccesoBD a = new AccesoBD();
            ArrayList<Obstaculo> obs = new ArrayList<>();
            obs = a.cargarObstaculos(con, id);
            for(int i = 0; i < (obs.size()); i++)
            {
                anadirObstaculo(obs.get(i));
            }
            con.close();
            
        } catch (IOException | ClassNotFoundException | SQLException ex) {
            Logger.getLogger(Escenario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public char proximaCelda(int x, int y) //Pregunto si la celda esta libre o no. En caso de no estarlo sabre quien la ocupa segun el char codigoOcupante
    {
        char c = 'n';
        if(((x >= 0) && (x <= 248)) && ((y >= 0) && (y <= 139)))
        {
            if(matriz[x][y] != null)
            {
                c = matriz[x][y].getOcupante();
            }
        }
        return c;
    }
    
    public boolean ocuparCelda(int x, int y, char codigoOcupante) //Registro que la celda en la posicion x y estara ocupada por el actor a quien corresponda el codigo. Devuelvo true si se ocupo con exito. PRECONDICION: la celda no esta ocupada
    {
        boolean exito;
        if(matriz[x][y] != null)
        {
            matriz[x][y].setOcupante(codigoOcupante);
            exito = true;
        }
        else
        {
            exito = false;
        }
        return exito;
    }
    
    public void liberarCelda(int x, int y)
    {
        matriz[x][y].setOcupante('0');
    }
    
    private void inicializarMatriz()
    {
        for(int i = 0; i < (largo / 5); i++)
        {
            for(int j = 0; j < (ancho / 5); j++)
            {
                matriz[i][j] = new Celda();
            }
        }
    }
    
    public void anadirObstaculo(Obstaculo obs)
    {
        for(int i = (obs.getPosicionX() / TAM_CELDA); i <= ((obs.getPosicionX() / TAM_CELDA) + (obs.getBase() / TAM_CELDA)); i++)
        {
            for(int j = (obs.getPosicionY() / TAM_CELDA); j <= ((obs.getAltura() / TAM_CELDA) + (obs.getPosicionY() / TAM_CELDA)); j++)
            {
                matriz[i][j].setOcupante(obs.getCodOcupante());
                matriz[i][j].setClave(obs.getClave());
            }
        }
    }
    
    public void anadirObstaculo(int clave, int esqSuperiorIzqX, int esqSuperiorIzqY, int esqInferiorDerX, int esqInferiorDerY, char tipo)
    {
        Obstaculo obs = new Obstaculo(clave, (esqSuperiorIzqX / TAM_CELDA), (esqSuperiorIzqY / TAM_CELDA   ), (esqInferiorDerY - esqSuperiorIzqY) / 5, (esqInferiorDerX - esqSuperiorIzqX) / 5, tipo);
        this.anadirObstaculo(obs);
    }
    
    public Coordenada destruirObstaculo(int clave)
    {
        Coordenada c = new Coordenada(0, 0);
        try 
        {
            Properties p = new Properties();
            String nomArch = "datos.properties";
            InputStream in;
            in = CreadorBD.class.getResourceAsStream(nomArch);
            p.load(in);
            String url = p.getProperty("url");
            String user = p.getProperty("user");
            String pass = p.getProperty("pass");
            in.close();
            
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection(url + "partidasguardadas", user, pass);
            AccesoBD a = new AccesoBD();
            Obstaculo o = a.cargarObstaculo(con, clave);
            
            c.setX(o.getPosicionX());
            c.setY(o.getPosicionY());
            
            for(int i = (o.getPosicionX() / TAM_CELDA); i <= ((o.getPosicionX() + o.getBase()) / TAM_CELDA); i++)
            {
                for(int j = (o.getPosicionY() / TAM_CELDA); j <= ((o.getPosicionY() + o.getAltura()) / TAM_CELDA); j++)
                {
                    matriz[i][j].setOcupante('0');
                }
            }
        } 
        catch (IOException | ClassNotFoundException | SQLException ex) 
        {
            Logger.getLogger(Escenario.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return c;
    }
    
    public Coordenada destruirObstaculo(int x, int y)
    {
        return destruirObstaculo(matriz[x / TAM_CELDA][y / TAM_CELDA].getClave());
    }

    // Getter and setters 
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getLargo() {
        return largo;
    }

    public void setLargo(int largo) {
        this.largo = largo;
    }

    public int getAncho() {
        return ancho;
    }

    public void setAncho(int ancho) {
        this.ancho = ancho;
    }
    
    public Celda[][] getMatriz()
    {
        return matriz;
    }
}

